﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace HooIzDat.Web.Models
{
    public class GameRepository : Repository, IGameRepository
    {
        public IQueryable<Game> FindAllGames()
        {
            return Db.Games;
        }

        public IQueryable<Game> FindPendingGames()
        {
            var pendingCutoffDate = DateTime.Now.AddMinutes(-Game.PendingGameTimeoutMinutes);
            return from g in Db.Games
                   where g.Player1ID != null &&
                         g.Player2ID == null &&
                         g.CreatedOn > pendingCutoffDate
                   orderby g.CreatedOn
                   select g;
        }

        public IQueryable<Game> FindActiveGames()
        {
            var activeCutoffDate = DateTime.Now.AddMinutes(-Game.PendingGameTimeoutMinutes);
            return from g in Db.Games
                   where g.Player1 != null &&
                         !g.FinishedOn.HasValue &&
                         g.CreatedOn > activeCutoffDate
                   orderby g.CreatedOn
                   select g;
        }

        public IQueryable<Game> FindFinishedGames()
        {            
            return Db.Games.AsAggregate().Where(g => g.FinishedOn.HasValue);
        }

        public Game GetGame(int id)
        {
            return Db.Games.AsAggregate().SingleOrDefault(g => g.GameID == id);
        }

        public void Add(Game game)
        {
            Db.Games.AddObject(game);
        }

        public void Delete(Game game)
        {
            DeleteTiles(game);

            if (game.GameState != null)
            {
                Db.GameStates.DeleteObject(game.GameState);
            }
            Db.Games.DeleteObject(game);
        }

        public void Delete(IEnumerable<Game> games)
        {
            foreach (var game in games)
            {
                Delete(game);
            }
        }

        private void DeleteTiles(Game game)
        {
            var tiles = game.Tiles.ToList();
            foreach (var tile in tiles)
            {
                Db.GameTiles.DeleteObject(tile);
            }
        }

        private void Delete(GameTile tile)
        {
            Db.GameTiles.DeleteObject(tile);
        }

        public void DeleteAll()
        {
            Delete(Db.Games.AsAggregate());
        }

        public void Save()
        {
            Db.SaveChanges();
        }
    }
}